import { DeleteOutlined, DeploymentUnitOutlined, EditOutlined, FileAddTwoTone } from "@ant-design/icons";
import {
    ActionType,
    ModalForm,
    PageContainer,
    ProForm,
    ProFormSelect,
    ProFormText,
    ProFormTextArea,
    ProList
} from "@ant-design/pro-components"
import { Alert, Button, Space, Image, Popover, Tag, Popconfirm, Modal, Spin } from "antd"
import React from "react"
import { useModel } from '@umijs/max';
import { loadTableData, typeOptions } from "./props"
import { save, deleteById, deploymentModel, modelById } from "./props/service";
import defaultImg from '@/assets/default.png';
import './index.less';
import { EasyFlowable } from "easy-flowable-react"

export default () => {

    const { initialState } = useModel('@@initialState');
    const { users, groups } = initialState;
    const list = React.useRef<ActionType>();
    const [state, setState] = React.useState<{ dataInfo: any; open: boolean; title: string; loading: boolean; }>({
        open: false,
        title: '',
        dataInfo: {},
        loading: false
    });

    const reloadTable = () => {
        // @ts-ignore
        list.current?.reloadAndRest();
    }

    React.useEffect(() => {
        if (!state.open) {
            reloadTable();
        }
    }, [state.open])

    return <PageContainer title="流程模型">
        <ProList ghost itemCardProps={{ ghost: true }} grid={{ gutter: 16, column: 4 }}
            request={loadTableData}
            actionRef={list}
            style={{ padding: 0 }}
            rowKey="id"
            pagination={{ pageSize: 8, pageSizeOptions: [8, 16, 32], showSizeChanger: true }}
            search={{}}
            metas={{
                title: {
                    dataIndex: 'name',
                    title: '模型名称'
                },
                subTitle: {
                    valueType: 'select',
                    dataIndex: 'modelType',
                    request: async () => typeOptions,
                    title: '流程类型'
                },
                avatar: {
                    render: (dom, record) => <Tag
                        color={record.publishVersion > 0 ? 'success' : 'blue'}>
                        {record.publishVersion > 0 ? `V${record.publishVersion}` : '暂未部署'}
                    </Tag>,
                    search: false,
                },
                type: {
                    dataIndex: 'key',
                    title: '流程标识'
                },
                content: {
                    search: false,
                    render: (dom, record) => {
                        return <Space>
                            <Image width='190px' height="100px" preview={false} src={record.picture || defaultImg} />
                            <Popover title={record.remarks && '描述'} content={record.remarks && record.remarks}>
                                <Space direction="vertical">
                                    <span>流程标识: {record.key}</span>
                                    <span>更新时间：{record.updateTime}</span>
                                </Space>
                            </Popover>
                        </Space>
                    }
                },
                actions: {
                    search: false,
                    cardActionProps: 'actions',
                    render: (dom, record) => [
                        <Popconfirm title="提示" key={'deployment_' + record.id} description="是否部署该模型？部署后启动的流程将以最新版本为主！" onConfirm={async () => {
                            const res = await deploymentModel(record.id);
                            if (res.success) {
                                reloadTable();
                            }
                        }}>
                            <Button type='link'  icon={<DeploymentUnitOutlined />}>部署</Button>
                        </Popconfirm>,
                        <Popover key={'edit_' + record.id} content="可视化编辑器">
                            <Button type='link'  icon={<EditOutlined />} onClick={() => {
                                setState({ dataInfo: record, open: true, title: record.name })
                            }}>编辑</Button>
                        </Popover>,
                        <Popconfirm title="提示" key={'delete_' + record.id} description="是否确认删除该模型？" onConfirm={async () => {
                            const res = await deleteById(record.id);
                            if (res.success) {
                                reloadTable();
                            }
                        }}>
                            <Button type='link' danger  icon={<DeleteOutlined />}>删除</Button>
                        </Popconfirm>
                    ],
                },
            }}
            headerTitle={<ModalForm title="创建一个新的业务流程模型" width="30%" onFinish={async (params) => {
                console.log(params)
                const res = await save(params);
                if (res.success) {
                    reloadTable();
                }
                return res.success;
            }} modalProps={{ destroyOnClose: true }} trigger={<Button icon={<FileAddTwoTone />}>新增模型</Button>}>
                <Alert message="您需要为新模型命名，并且您可以在这个操作中添加描述信息。" />
                <ProFormSelect name="modelType" label="模型类型" options={typeOptions} rules={[{ required: true, message: '模型标识不能为空' }]} />
                <ProFormText name="name" label="模型名称" rules={[{ required: true, message: '模型名称不能为空' }, { max: 60, message: '模型名称长度最多60个字符' }]} />
                <ProFormText name="key" label="模型标识" rules={[
                    {
                        required: true,
                        validator: (_, value, callback) => {
                            if (!value) {
                                return Promise.reject(new Error('模型标识不能为空!'));
                            }
                            if (value.length > 60) {
                                return Promise.reject(new Error('模型标识长度最多60个字符!'));
                            }
                            if (!isNaN(value)) {
                                return Promise.reject(new Error('模型标识不能为纯数字!'));
                            }
                            if (/[\u4e00-\u9fa5]/g.test(value)) {
                                return Promise.reject(new Error('模型标识不能有中文!'));
                            }
                            return Promise.resolve();
                        }
                    }
                ]} />
                <ProFormTextArea name="remarks" label="描述" />
            </ModalForm>} />
        <Modal title={<ProForm
            layout="inline"
            request={() => state.dataInfo}
            onFinish={async (values) => {
                await save({ id: state.dataInfo.id, ...values });
            }}>
                <ProFormSelect name="modelType" label="模型类型" options={typeOptions}
                    rules={[{ required: true, message: '模型标识不能为空' }]} />
                <ProFormText name="name" label="模型名称"
                    rules={[
                        { required: true, message: '模型名称不能为空' },
                        { max: 60, message: '模型名称长度最多60个字符' }
                    ]} />
                <ProFormText name="remarks" width="lg" label="描述" />
            </ProForm>}
            open={state.open}
            destroyOnClose
            onCancel={() => setState({ ...state, open: false })}
            centered width="100%"
            keyboard mask={false}
            footer={false}>
            <Spin spinning={state.loading}>
                <EasyFlowable
                    height={84}
                    flowKey={state.dataInfo.key}
                    flowName={state.dataInfo.name}
                    request={async () => {
                        setState({ ...state, loading: true })
                        const { result } = await modelById(state.dataInfo.id);
                        setState({ ...state, loading: false })
                        return result.modelEditorXml;
                    }}
                    toolbar={{
                        isBase64: true,
                        save: async (data) => {
                            setState({ ...state, loading: true })
                            setTimeout(async () => {
                                const { success, result } = await save({ ...state.dataInfo, modelEditorXml: data.xml, picture: data.base64, remarks: data.description, name: data.name });
                                if (success) {
                                    setState({ ...state, loading: false });
                                    reloadTable();
                                }
                            }, 1000);
                        }
                    }}
                    panel={{ users, groups }} />
            </Spin>
        </Modal>
    </PageContainer>
}